//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package admin_widget_store_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas/api-server/admin_api_serv/admin_common"
	"atomgit.com/openlinksaas/api-server/config"
	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/fs_dao"
	"atomgit.com/openlinksaas/api-server/dao/widget_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/widget_store_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

type WidgetStoreAdminApiImpl struct {
	widget_store_api.UnimplementedWidgetStoreAdminApiServer
	adminCfg *config.AdminCfg
}

func NewWidgetStoreAdminApiImpl(adminCfg *config.AdminCfg) *WidgetStoreAdminApiImpl {
	return &WidgetStoreAdminApiImpl{adminCfg: adminCfg}
}

func (apiImpl *WidgetStoreAdminApiImpl) AddWidget(ctx context.Context, req *widget_store_api.AdminAddWidgetRequest) (*widget_store_api.AdminAddWidgetResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &widget_store_api.AdminAddWidgetResponse{
			Code:   widget_store_api.AdminAddWidgetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &widget_store_api.AdminAddWidgetResponse{
			Code:   widget_store_api.AdminAddWidgetResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.WidgetStorePerm.AddWidget {
		return &widget_store_api.AdminAddWidgetResponse{
			Code:   widget_store_api.AdminAddWidgetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	//检查文件是否存在
	widgetStoreFsId, err := fs_dao.GlobalFsDao.GetWidgetStoreFs(ctx)
	if err != nil {
		return nil, err
	}
	exist, err := fs_dao.FsFileDao.Exist(ctx, widgetStoreFsId, req.FileId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminAddWidgetResponse{
			Code:   widget_store_api.AdminAddWidgetResponse_CODE_NO_FILE,
			ErrMsg: "文件不存在",
		}, nil
	}

	exist, err = fs_dao.FsFileDao.Exist(ctx, widgetStoreFsId, req.IconFileId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminAddWidgetResponse{
			Code:   widget_store_api.AdminAddWidgetResponse_CODE_NO_FILE,
			ErrMsg: "文件不存在",
		}, nil
	}

	widgetId := uuid.NewString()
	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = widget_dao.WidgetDao.Insert(sessCtx, &widget_dao.WidgetInfoDbItem{
			WidgetId:      widgetId,
			WidgetName:    req.WidgetName,
			ExtensionList: req.ExtensionList,
			FileList:      req.FileList,
			FileId:        req.FileId,
			IconFileId:    req.IconFileId,
			Weight:        req.Weight,
			CreateTime:    nowTime,
			UpdateTime:    nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &widget_store_api.AdminAddWidgetResponse{
			Code:     widget_store_api.AdminAddWidgetResponse_CODE_OK,
			WidgetId: widgetId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*widget_store_api.AdminAddWidgetResponse), nil
}

func (apiImpl *WidgetStoreAdminApiImpl) UpdateWidget(ctx context.Context, req *widget_store_api.AdminUpdateWidgetRequest) (*widget_store_api.AdminUpdateWidgetResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &widget_store_api.AdminUpdateWidgetResponse{
			Code:   widget_store_api.AdminUpdateWidgetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &widget_store_api.AdminUpdateWidgetResponse{
			Code:   widget_store_api.AdminUpdateWidgetResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.WidgetStorePerm.UpdateWidget {
		return &widget_store_api.AdminUpdateWidgetResponse{
			Code:   widget_store_api.AdminUpdateWidgetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := widget_dao.WidgetDao.Exist(ctx, req.WidgetId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminUpdateWidgetResponse{
			Code:   widget_store_api.AdminUpdateWidgetResponse_CODE_NO_WIDGET,
			ErrMsg: "插件不存在",
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = widget_dao.WidgetDao.Update(sessCtx, req.WidgetId, req.WidgetName, req.ExtensionList, req.FileList, nowTime)
		if err != nil {
			return nil, err
		}
		return &widget_store_api.AdminUpdateWidgetResponse{
			Code: widget_store_api.AdminUpdateWidgetResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*widget_store_api.AdminUpdateWidgetResponse), nil
}

func (apiImpl *WidgetStoreAdminApiImpl) UpdateIconFile(ctx context.Context, req *widget_store_api.AdminUpdateIconFileRequest) (*widget_store_api.AdminUpdateIconFileResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &widget_store_api.AdminUpdateIconFileResponse{
			Code:   widget_store_api.AdminUpdateIconFileResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &widget_store_api.AdminUpdateIconFileResponse{
			Code:   widget_store_api.AdminUpdateIconFileResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.WidgetStorePerm.UpdateWidget {
		return &widget_store_api.AdminUpdateIconFileResponse{
			Code:   widget_store_api.AdminUpdateIconFileResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := widget_dao.WidgetDao.Exist(ctx, req.WidgetId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminUpdateIconFileResponse{
			Code:   widget_store_api.AdminUpdateIconFileResponse_CODE_NO_WIDGET,
			ErrMsg: "插件不存在",
		}, nil
	}

	//检查文件是否存在
	widgetStoreFsId, err := fs_dao.GlobalFsDao.GetWidgetStoreFs(ctx)
	if err != nil {
		return nil, err
	}
	exist, err = fs_dao.FsFileDao.Exist(ctx, widgetStoreFsId, req.IconFileId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminUpdateIconFileResponse{
			Code:   widget_store_api.AdminUpdateIconFileResponse_CODE_NO_FILE,
			ErrMsg: "文件不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = widget_dao.WidgetDao.UpdateIcon(sessCtx, req.WidgetId, req.IconFileId)
		if err != nil {
			return nil, err
		}
		return &widget_store_api.AdminUpdateIconFileResponse{
			Code: widget_store_api.AdminUpdateIconFileResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*widget_store_api.AdminUpdateIconFileResponse), nil
}

func (apiImpl *WidgetStoreAdminApiImpl) UpdateFile(ctx context.Context, req *widget_store_api.AdminUpdateFileRequest) (*widget_store_api.AdminUpdateFileResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &widget_store_api.AdminUpdateFileResponse{
			Code:   widget_store_api.AdminUpdateFileResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &widget_store_api.AdminUpdateFileResponse{
			Code:   widget_store_api.AdminUpdateFileResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.WidgetStorePerm.UpdateWidget {
		return &widget_store_api.AdminUpdateFileResponse{
			Code:   widget_store_api.AdminUpdateFileResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := widget_dao.WidgetDao.Exist(ctx, req.WidgetId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminUpdateFileResponse{
			Code:   widget_store_api.AdminUpdateFileResponse_CODE_NO_WIDGET,
			ErrMsg: "插件不存在",
		}, nil
	}

	//检查文件是否存在
	widgetStoreFsId, err := fs_dao.GlobalFsDao.GetWidgetStoreFs(ctx)
	if err != nil {
		return nil, err
	}
	exist, err = fs_dao.FsFileDao.Exist(ctx, widgetStoreFsId, req.FileId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminUpdateFileResponse{
			Code:   widget_store_api.AdminUpdateFileResponse_CODE_NO_FILE,
			ErrMsg: "文件不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = widget_dao.WidgetDao.UpdateFile(sessCtx, req.WidgetId, req.FileId)
		if err != nil {
			return nil, err
		}
		return &widget_store_api.AdminUpdateFileResponse{
			Code: widget_store_api.AdminUpdateFileResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*widget_store_api.AdminUpdateFileResponse), nil
}

func (apiImpl *WidgetStoreAdminApiImpl) UpdateWeight(ctx context.Context, req *widget_store_api.AdminUpdateWeightRequest) (*widget_store_api.AdminUpdateWeightResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &widget_store_api.AdminUpdateWeightResponse{
			Code:   widget_store_api.AdminUpdateWeightResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &widget_store_api.AdminUpdateWeightResponse{
			Code:   widget_store_api.AdminUpdateWeightResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.WidgetStorePerm.UpdateWidget {
		return &widget_store_api.AdminUpdateWeightResponse{
			Code:   widget_store_api.AdminUpdateWeightResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := widget_dao.WidgetDao.Exist(ctx, req.WidgetId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminUpdateWeightResponse{
			Code:   widget_store_api.AdminUpdateWeightResponse_CODE_NO_WIDGET,
			ErrMsg: "插件不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = widget_dao.WidgetDao.UpdateWeight(sessCtx, req.WidgetId, req.Weight)
		if err != nil {
			return nil, err
		}
		return &widget_store_api.AdminUpdateWeightResponse{
			Code: widget_store_api.AdminUpdateWeightResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*widget_store_api.AdminUpdateWeightResponse), nil
}

func (apiImpl *WidgetStoreAdminApiImpl) RemoveWidget(ctx context.Context, req *widget_store_api.AdminRemoveWidgetRequest) (*widget_store_api.AdminRemoveWidgetResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &widget_store_api.AdminRemoveWidgetResponse{
			Code:   widget_store_api.AdminRemoveWidgetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &widget_store_api.AdminRemoveWidgetResponse{
			Code:   widget_store_api.AdminRemoveWidgetResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.WidgetStorePerm.RemoveWidget {
		return &widget_store_api.AdminRemoveWidgetResponse{
			Code:   widget_store_api.AdminRemoveWidgetResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := widget_dao.WidgetDao.Exist(ctx, req.WidgetId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &widget_store_api.AdminRemoveWidgetResponse{
			Code: widget_store_api.AdminRemoveWidgetResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = widget_dao.WidgetDao.Remove(sessCtx, req.WidgetId)
		if err != nil {
			return nil, err
		}
		return &widget_store_api.AdminRemoveWidgetResponse{
			Code: widget_store_api.AdminRemoveWidgetResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*widget_store_api.AdminRemoveWidgetResponse), nil
}
